package org.drushpal.service
{
	import flash.desktop.NativeProcess;
	import flash.display.Sprite;
	import flash.events.ProgressEvent;
	import flash.system.Capabilities;
	
	import mx.collections.ArrayCollection;
	import mx.controls.Alert;
	import mx.core.Application;
	import mx.core.FlexGlobals;
	import mx.events.CloseEvent;
	import mx.managers.CursorManager;
	import mx.managers.PopUpManager;
	import mx.utils.StringUtil;
	
	import org.drushpal.model.enum.DrushCommand;
	import org.drushpal.model.vo.Connection;
	import org.drushpal.model.vo.History;
	import org.drushpal.model.vo.Status;
	import org.drushpal.service.connecter.Connecter;
	import org.drushpal.service.connecter.Plink;
	import org.drushpal.service.connecter.SSH;
	import org.robotlegs.mvcs.Actor;
	
	public class DrushService extends Actor
	{
		public var connection:Connection;
		public var initialArgs:String;
		
		/**
		 * 
		 **/
		[Bindable]
		public var terminal:String;
		[Bindable]
		public var statusCollection:ArrayCollection;
		[Bindable]
		public var projectsCollection:ArrayCollection;
		[Bindable]
		public var variablesCollection:ArrayCollection;
		
		[Bindable]
		public var running:ArrayCollection;
		private var currentConnection:Connecter;
		
		private var _args:String;
		
		public function DrushService()
		{
			
		}
		
		
		public function start(con:Connection):void{
			currentConnection = getConnecter();
			currentConnection.connect(con);
			running = new ArrayCollection();
			terminal = "";
			connection = con;			
			initialArgs = "cd " + connection.root + ";";
			if(con.drushpath.length){
				initialArgs+=con.drushpath+" ";
			}else{
				initialArgs+="drush ";
			}
			//initialArgs.push("--debug");
		}
		public function stop():void{
			if(currentConnection && currentConnection.process.running){
				currentConnection.process.exit(true);
			}
		}
		
		/**
		 * Decide which OS we are running and then run the appropriate SSH tool. On windows this is plink (putty) and on Mac/Linux it's OpenSSH
		 */
		public function getConnecter():Connecter{
			var connecter:Connecter;
			if(Capabilities.os.indexOf("Win")!=-1){//oh noes, windows!
				connecter = new Plink(onError,onComplete,eventDispatcher);
			}else{
				connecter = new SSH(onError,onComplete,eventDispatcher);
			}
			return connecter;
		}		
		
		public function run(command:String,args:Array=null):void{			
			_args = initialArgs;
			
			running.addItem(new History(command,History.STATUS_RUNNING));
			switch(command){				
				case DrushCommand.LIST:
				case DrushCommand.REFRESH:		
				case DrushCommand.STATUS:
				case DrushCommand.CRON:
				case DrushCommand.VARIABLE_GET:
					currentConnection.addCommand(_args+=command,command);
				break;
				
				case DrushCommand.DOWNLOAD:
					_args+=DrushCommand.DOWNLOAD + " " + args.join(" ");
					currentConnection.addCommand(_args,command);
				break;
				
				case DrushCommand.CLEAR_CACHE:
					_args+=DrushCommand.CLEAR_CACHE + " " + args[0].toString();
					currentConnection.addCommand(_args,command);
				break;
			}
			terminal+=_args;
		}
		
		//errors that happen from calling drush or ssh/plink
		private function onError(output:String,con:Connecter):void{
			var a:Alert;
			if(output.indexOf("y/n") != -1 || output.indexOf("y\\n") != -1){
				//this is a yes no response
				a = Alert.show(output,"Message",Alert.YES|Alert.NO,FlexGlobals.topLevelApplication as Sprite,onCloseError);
				a.data = new Object();
				a.data.con = con;
			}else{
				//not sure...
				Alert.show(output,"Message");
				if(running && running.length){
					History(running.getItemAt(running.length-1)).status = History.STATUS_COMPLETE; //was error... but this happens sometimes when it's not an error. No reliable way to tell if a message or error.
				}
			}
		}
		private function onCloseError(event:CloseEvent):void{
			var con:Connecter = event.currentTarget.data.con as Connecter;
			if(event.detail == Alert.YES){
				con.process.standardInput.writeUTFBytes("y\n");//yes
			}else{
				con.process.standardInput.writeUTFBytes("n\n");//no
			}
		}		
		
		private function onComplete(output:String):void{
			terminal+=output+"\n";
			FlexGlobals.topLevelApplication.cursorManager.removeBusyCursor();
			if(running && running.length){
				History(running.getItemAt(running.length-1)).status = History.STATUS_COMPLETE;
			} 
		}
	}
}